package entity

import (
	"database/sql"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
	"github.com/json-iterator/go"
	"nspel/nspel"
	"strconv"
	"time"
)

const AreaTypeReport = 0
const SchoolTypeReport = 1
const GradeTypeReport = 2
const ClassTypeReport = 3
const PersonTypeReport = 3

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type Report struct {
	Id               int64          `orm:"pk;auto;column(id)"`
	ProvinceId       int64          `orm:"column(province_id)"`
	CityId           int64          `orm:"column(city_id)"`
	AreaId           int64          `orm:"column(area_id)"`
	ExperimentAreaId int64          `orm:"column(experiment_area_id)"`
	SchoolId         int64          `orm:"column(school_id)"`
	Type             byte           `orm:"column(type)"`
	Info             sql.NullString `orm:"column(info)"`
	Tip              sql.NullString `orm:"column(tip)"`
	CreatedAt        time.Time      `orm:"auto_now_add;column(created_at)"`
	Url              sql.NullString `orm:"column(url)"`
	IsUpdate         bool           `orm:"column(is_update)"`
	MeasureTime      time.Time      `orm:"column(measure_time)"`
}

func init() {
	orm.RegisterModel(new(Report))
}

func (*Report) TableName() string {
	return "report"
}

func (r *Report) Insert() error {
	_, err := nspel.GetOrmEngine().Insert(r)
	return err
}

func (r *Report) SelectAllBySchoolIdInfoMeasureTime(schoolId int64, info string, measureTime time.Time) error {
	key := "report"
	hashKey := "schoolId[" + strconv.FormatInt(schoolId, 10) + "].info[\"" + info + "\"].measureTime[" + measureTime.String() + "]"
	err := nspel.RedisHgetJson(key, hashKey, r)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	r.SchoolId = schoolId
	r.Info.String = info
	r.MeasureTime = measureTime
	err = nspel.GetOrmEngine().QueryTable(r.TableName()).Filter("school_id", r.SchoolId).Filter("info", r.Info.String).Filter("measure_time", r.MeasureTime.Format("2006-01-02")).One(r)
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, r)
	return nil
}

func (r *Report) Update(column ...string) error {
	_, err := nspel.GetOrmEngine().Update(r, column...)
	return err
}

func (r *Report) SelectDistinctSchoolIds() (orm.ParamsList, error) {
	key := "report"
	hashKey := "schoolIds"
	var data orm.ParamsList
	err := nspel.RedisHgetJson(key, hashKey, &data)
	if err == nil {
		return data, nil
	}
	_, err = nspel.GetOrmEngine().QueryTable(r.TableName()).Distinct().ValuesFlat(&data, "school_id")
	if err != nil {
		return data, err
	}
	nspel.RedisHsetJson(key, hashKey, data)
	return data, nil
}

func (r *Report) CustomCount(ormEng *orm.QuerySeter, hashKey string) (count int64, err error) {
	key := "report"
	count, err = nspel.RedisHgetInt64(key, hashKey)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	count, err = (*ormEng).Count()
	if err != nil {
		return
	}
	nspel.RedisHsetInt64(key, hashKey, count)
	return
}

func (r *Report) CustomSelect(ormEng *orm.QuerySeter, hashKey string) (reports []Report, err error) {
	key := "report"
	err = nspel.RedisHgetJson(key, hashKey, &reports)
	if err == nil {
		return
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	_, err = (*ormEng).All(&reports)
	if err != nil || len(reports) == 0 {
		return
	}
	nspel.RedisHsetJson(key, hashKey, reports)
	return
}

func (r *Report) SelectAllById(id int64) (err error) {
	key := "report"
	hashKey := "id[" + strconv.FormatInt(id, 10) + "]"
	err = nspel.RedisHgetJson(key, hashKey, r)
	if err == nil {
		return nil
	}
	if err != redis.ErrNil {
		nspel.Error(err)
	}
	r.Id = id
	err = nspel.GetOrmEngine().Read(r)
	if err != nil {
		return err
	}
	nspel.RedisHsetJson(key, hashKey, r)
	return nil
}
